//
// Created by mazaiting on 2024/4/29.
//

#include <iostream>
#include <queue>
#include <string>

using namespace std;

class Stud                //定义类Stud
{
public:
    int no;                //学号
    string name;            //姓名
    Stud(int n, string na)        //构造函数
    {
        no = n;
        name = na;
    }

    bool operator<(const Stud &s) const    //重载<比较函数
    {                    //将当前对象跟对象s进行比较
        return no < s.no;        //按no越大越优先出队
    }

    bool operator>(const Stud &s) const    //重载>比较函数
    {                    //将当前对象跟对象s进行比较
        return no > s.no;        //按no越小越优先出队
    }
};

//类的比较函数,改写operator()
class StudCmp                //含重载()成员函数的类
{
public:
    bool operator()(const Stud &s, const Stud &t) const {                    //将对象s跟对象t进行比较
        return s.name < t.name;        //按name越大越优先出队
    }
};

int main() {
    Stud a[] = {Stud(2, "Mary"), Stud(1, "John"), Stud(5, "Smith")};
    int n = sizeof(a) / sizeof(a[0]);
    //************************************************
    //方式1：使用Stud类的<比较函数定义大根堆pq1
    //************************************************
    priority_queue<Stud> pq1(a, a + n);
    cout << "pq1出队顺序: ";
    while (!pq1.empty())            //按no递减输出
    {
        cout << "[" << pq1.top().no << "," << pq1.top().name << "]\t";
        pq1.pop();
    }
    cout << endl;
//************************************************
//方式2：使用Stud类的>比较函数定义小根堆pq2
//************************************************
    priority_queue<Stud, deque<Stud>, greater<> > pq2(a, a + n);
    cout << "pq2出队顺序: ";
    while (!pq2.empty())            //按no递增输出
    {
        cout << "[" << pq2.top().no << "," << pq2.top().name << "]\t";
        pq2.pop();
    }
    cout << endl;
    //************************************************
    //方式3：使用类StudCmp的比较函数定义大根堆pq3
    //************************************************
    priority_queue<Stud, deque<Stud>, StudCmp> pq3(a, a + n);
    cout << "pq3出队顺序: ";
    while (!pq3.empty())            //按name递减输出
    {
        cout << "[" << pq3.top().no << "," << pq3.top().name << "]\t";
        pq3.pop();
    }
    cout << endl;
    return 0;
}



